package cn.net.autocode.platform.auth.service;

import cn.hutool.core.lang.Validator;
import cn.net.autocode.core.utils.JwtUtils;
import cn.net.autocode.core.utils.PasswordUtils;
import cn.net.autocode.core.utils.UserThreadLocalUtils;
import cn.net.autocode.dbManager.Dao;
import cn.net.autocode.dbManager.SqlWrapper;
import cn.net.autocode.dbManager.SqlWrapperBuilder;
import cn.net.autocode.platform.cache.AutoCacheUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Service;
import java.util.Date;

@Service
public class PlatformAuthServ {

    private final Dao dao;


    private final AutoCacheUtil cacheUtil;

    public PlatformAuthServ(Dao dao, AutoCacheUtil cacheUtil) {
        this.dao = dao;
        this.cacheUtil = cacheUtil;
    }

    /**
     * 用户登录
     *
     * @return 用户信息
     */
    public JSONObject accountLogin(String account, String password, String isMobile) {
        //认证方式，1：用户名，2：电话、邮箱 3：用户名+电话+邮箱
        String authType = dao.queryValue("select auth_type from autocode_platform", String.class);
        SqlWrapperBuilder swb = new SqlWrapperBuilder("sys_users");
        swb.selectColumn("username,passwrd,status,fullname,last_login_org,email,phone");
        if ("1".equals(authType)) {
            if (Validator.isEmail(account)) {
                swb.eq("email", account);
            } else if (Validator.isMobile(account)) {
                swb.eq("phone", account);
            } else {
                swb.eq("username", "-1");
            }
        } else if ("2".equals(authType)) {
            if (Validator.isEmail(account)) {
                swb.eq("email", account);
            } else if (Validator.isMobile(account)) {
                swb.eq("phone", account);
            } else {
                throw new RuntimeException("请使用邮箱或手机号登录");
            }
        } else if ("3".equals(authType)) {
            if (Validator.isEmail(account)) {
                swb.eq("email", account);
            } else {
                throw new RuntimeException("请使用邮箱登录");
            }
        } else if ("4".equals(authType)) {
            if (Validator.isMobile(account)) {
                swb.eq("phone", account);
            } else {
                throw new RuntimeException("请使用手机号登录");
            }
        } else {
            swb.eq("username", account.toLowerCase());
        }

        SqlWrapper sqlWrapper = swb.sqlWrapper();
        //用户表
        JSONObject sysUser = dao.queryJSON(sqlWrapper.getSql(), sqlWrapper.getParams().toArray());
        return this.userLogin(sysUser, password, isMobile);
    }

    /**
     * 用户登录
     *
     * @return 用户信息
     */
    public JSONObject ssoMobile(String mobile,String isMobile) {
        SqlWrapperBuilder swb = new SqlWrapperBuilder("sys_users");
        swb.selectColumn("username,passwrd,status,fullname,last_login_org,email,phone");
        if (Validator.isMobile(mobile)) {
            swb.eq("phone", mobile);
        } else {
            throw new RuntimeException("用户手机号维护错误，不能进行免登录！");
        }

        SqlWrapper sqlWrapper = swb.sqlWrapper();
        //用户表
        JSONArray sysUserArray = dao.queryJSONArray(sqlWrapper.getSql(), sqlWrapper.getParams().toArray());

        JSONObject rs = new JSONObject();
        rs.put("code", 0);

        JSONObject sysUser;
        if (sysUserArray.isEmpty()) {
            rs.put("msg", "没有维护"+mobile+"对应用户信息,请先在系统中完善对应账号的手机号信息！");
            return rs;
        }else if(sysUserArray.size()>1){
            rs.put("msg", "系统中"+mobile+"对应的用户不唯一，请联系管理员出来！");
            return rs;
        }else{
            sysUser = sysUserArray.getJSONObject(0);
        }

        //判断状态
        if (!"Active".equals(sysUser.getString("status"))) {
            switch (sysUser.getString("status")) {
                case "Hold" -> rs.put("msg", "用户未激活，请联系管理员激活！");
                case "Locked" -> rs.put("msg", "账号被冻结，请联系管理员解锁！");
                case "Retired" -> rs.put("msg", "账号已弃用，请联系管理员恢复！");
                default -> rs.put("msg", "账号状态异常，请联系管理员处理！");
            }
            return rs;
        }

        // 生成token
        String userName = sysUser.getString("username");
        String hashed = sysUser.getString("passwrd");
        String token = JwtUtils.sign(userName, hashed);

        //获取组织机构列表
        JSONArray orgList = dao.queryJSONArray("select t1.code,t1.label from sys_organ t1,sys_organ_users t2 where t1.code=t2.org_code and username=? order by t1.code", userName);
        if (orgList.isEmpty()) {
            rs.put("msg", "您还未加入任务组织，不能登录系统！");
            return rs;
        } else {
            String lastLoginOrg = sysUser.getString("lastLoginOrg");
            rs.put("lastLoginOrg", lastLoginOrg);
            sysUser.remove("orgCode");
            rs.put("code", 2);

            JSONArray sortOrgList = new JSONArray();
            //orgList排序
            for (int i = 0; i < orgList.size(); i++) {
                JSONObject org = orgList.getJSONObject(i);
                if (org.getString("code").equals(lastLoginOrg)) {
                    sortOrgList.add(0, org);
                } else {
                    sortOrgList.add(org);
                }
            }
            rs.put("orgList", sortOrgList);
        }


        if (orgList.size() == 1) {
            JSONObject sysOrgan = orgList.getJSONObject(0);
            sysUser.put("orgCode", sysOrgan.getString("code"));
            sysUser.put("orgName", sysOrgan.getString("label"));
            rs.put("orgCode", sysOrgan.getString("code"));
            rs.put("orgName", sysOrgan.getString("label"));
            rs.put("code", 1);
        }

        // 设置token缓存有效时间
        cacheUtil.setToken(token, sysUser, isMobile);
        rs.put("username", userName);
        rs.put("token", token);
        rs.put("fullname", sysUser.getString("fullname"));
        return rs;

    }


    /**
     * 用户登录
     *
     * @return 用户信息
     */
    public JSONObject tokenReLogin(String username, String password, String isMobile) {
        //认证方式，1：用户名，2：电话、邮箱 3：用户名+电话+邮箱
        SqlWrapperBuilder swb = new SqlWrapperBuilder("sys_users");
        swb.selectColumn("username,passwrd,status,fullname,last_login_org");
        swb.eq("username", username.toUpperCase());

        SqlWrapper sqlWrapper = swb.sqlWrapper();
        //用户表
        JSONObject sysUser = dao.queryJSON(sqlWrapper.getSql(), sqlWrapper.getParams().toArray());

        JSONObject rs = this.userLogin(sysUser, password, isMobile);
        if (rs.getIntValue("code") == 0) {
            return rs;
        } else {
            if (rs.getString("lastLoginOrg") != null && !rs.getString("lastLoginOrg").isBlank()) {
                rs.put("code", 1);
                String token = rs.getString("token");
                JSONObject organ = dao.queryJSON("select t1.label,t1.code from sys_organ t1,sys_organ_users t2 where t1.code=t2.org_code and t2.username=? and t2.org_code=?", username.toUpperCase(), rs.getString("lastLoginOrg"));
                if (organ.isEmpty()) {
                    cacheUtil.delToken(token, isMobile);
                    rs.put("code", 0);
                    rs.put("msg", "您没有访问该组织的权限！");
                } else {
                    sysUser.put("orgCode", organ.getString("code"));
                    sysUser.put("orgName", organ.getString("label"));
                    cacheUtil.setToken(token,sysUser, isMobile);
                }
            }
            return rs;
        }
    }

    private JSONObject userLogin(JSONObject sysUser, String password, String isMobile) {
        JSONObject rs = new JSONObject();
        rs.put("code", 0);

        if (sysUser.isEmpty()) {
            rs.put("msg", "账号或密码错误");
            return rs;
        }

        //密码验证
        String hashed = sysUser.getString("passwrd");
        if (!PasswordUtils.checkpw(password, hashed)) {
            rs.put("msg", "账号或密码错误");
            return rs;
        }

        //判断状态
        if (!"Active".equals(sysUser.getString("status"))) {
            switch (sysUser.getString("status")) {
                case "Hold" -> rs.put("msg", "用户未激活，请联系管理员激活！");
                case "Locked" -> rs.put("msg", "账号被冻结，请联系管理员解锁！");
                case "Retired" -> rs.put("msg", "账号已弃用，请联系管理员恢复！");
                default -> rs.put("msg", "账号状态异常，请联系管理员处理！");
            }
            return rs;
        }

        // 生成token
        String userName = sysUser.getString("username");
        String token = JwtUtils.sign(userName, hashed);

        //获取组织机构列表
        JSONArray orgList = dao.queryJSONArray("select t1.code,t1.label from sys_organ t1,sys_organ_users t2 where t1.code=t2.org_code and username=? order by t1.code", userName);
        if (orgList.isEmpty()) {
            rs.put("msg", "您还未加入任务组织，不能登录系统！");
            return rs;
        } else {
            String lastLoginOrg = sysUser.getString("lastLoginOrg");
            rs.put("lastLoginOrg", lastLoginOrg);
            sysUser.remove("orgCode");
            rs.put("code", 2);

            JSONArray sortOrgList = new JSONArray();
            //orgList排序
            for (int i = 0; i < orgList.size(); i++) {
                JSONObject org = orgList.getJSONObject(i);
                if (org.getString("code").equals(lastLoginOrg)) {
                    sortOrgList.add(0, org);
                } else {
                    sortOrgList.add(org);
                }
            }
            rs.put("orgList", sortOrgList);
        }


        if (orgList.size() == 1) {
            JSONObject sysOrgan = orgList.getJSONObject(0);
            sysUser.put("orgCode", sysOrgan.getString("code"));
            sysUser.put("orgName", sysOrgan.getString("label"));

            //获取部门信息
            String sql = "select t1.dept label,t1.id value from sys_departments t1,sys_department_user t2 where t1.id=t2.dept_id and t1.org_code=? and t2.username=?";
            JSONArray deptList = dao.queryJSONArray(sql,sysOrgan.getString("code"),userName);
            sysUser.put("deptList", deptList);
            rs.put("orgCode", sysOrgan.getString("code"));
            rs.put("orgName", sysOrgan.getString("label"));
            rs.put("code", 1);
        }

        // 设置token缓存有效时间
        cacheUtil.setToken(token, sysUser, isMobile);
        rs.put("username", userName);
        rs.put("token", token);
        rs.put("fullname", sysUser.getString("fullname"));
        return rs;
    }


    public void loginLog(String userName,String clientIp,String orgCode,String isMobile) {
        JSONObject userLog = new JSONObject();
        userLog.put("username",userName);
        if ("Y".equals(isMobile)) {
            userLog.put("message","移动端--登录成功");
        }else{
            userLog.put("message","PC端--登录成功");
        }

        userLog.put("logName","login");
        userLog.put("dateTime",new Date());
        userLog.put("clientIp", clientIp);
        userLog.put("orgCode",orgCode);
        dao.createJSON(userLog,"sys_user_log");
    }

    public void logoutLog(String token, String isMobile,String clientIp) {
        JSONObject userLog = new JSONObject();
        JSONObject user = UserThreadLocalUtils.get();
        if (user==null){
            userLog.put("username", JwtUtils.getUsername(token));
            if ("Y".equals(isMobile)) {
                userLog.put("message","移动端--退出登录");
            }else{
                userLog.put("message","PC端--退出登录");
            }
            userLog.put("logName","logout");
            userLog.put("dateTime",new Date());
            userLog.put("clientIp", clientIp);
            dao.createJSON(userLog,"sys_user_log");
        }else{
            userLog.put("username", UserThreadLocalUtils.getUserName());
            if ("Y".equals(isMobile)) {
                userLog.put("message","移动端--退出登录");
            }else{
                userLog.put("message","PC端--退出登录");
            }
            userLog.put("logName","logout");
            userLog.put("dateTime",new Date());
            userLog.put("clientIp", clientIp);
            userLog.put("orgCode",UserThreadLocalUtils.getOrgCode());
            dao.createJSON(userLog,"sys_user_log");
        }

    }


}
